package com.ruoyi.lvlian.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.MD5Utils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.lvlian.domain.*;
import com.ruoyi.lvlian.dto.*;
import com.ruoyi.lvlian.mapper.InvoiceInfoMapper;
import com.ruoyi.lvlian.mapper.PaymentInfoMapper;
import com.ruoyi.lvlian.service.ICommonService;
import com.ruoyi.lvlian.service.InvoiceInfoService;
import com.ruoyi.lvlian.util.ExcelUtil;
import com.ruoyi.lvlian.vo.DashboardVo;
import com.ruoyi.lvlian.vo.InvoiceVo;
import com.ruoyi.lvlian.vo.PaymentInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 发票信息Service业务层处理
 *
 * @author liyuxi
 * @date 2024-05-09
 */
@Service
public class InvoiceInfoServiceImpl implements InvoiceInfoService {
    @Autowired
    private InvoiceInfoMapper invoiceInfoMapper;

    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

    /**
     * 查询发票信息
     *
     * @param id 发票信息主键
     * @return 发票信息
     */
    @Override
    public InvoiceVo selectInvoiceInfoById(String id) {
        InvoiceVo po= invoiceInfoMapper.selectInvoiceInfoById(id);
        if(StringUtils.isEmpty(po.getInvoiceImg() )){
            invoiceInfoMapper.updateImg( po.getInvoiceNum(),"invoice_img"  );
        }
        return  po;
    }

    /**
     * 查询发票信息列表
     *
     * @param invoiceInfo 发票信息
     * @return 发票信息
     */
    @Override
    public List<InvoiceVo> selectInvoiceInfoList(InvoiceInfoDto invoiceInfo) {


        List<InvoiceVo> resultlist = new ArrayList<>(); // 发票关联支付
        if (invoiceInfo.getTaxRate().contains("13")) {// 税率为 13% 时, 关联利废入库查询
            invoiceInfo.setTaxRate("13");
            // 发票-支付-利废入库三表联查
            resultlist = invoiceInfoMapper.selectInvoiceePaymentRefAndRecyclingRef(invoiceInfo);

        } else if (invoiceInfo.getTaxRate().contains("3")) {// 税率为 3% 时, 关联再生入库查询
            invoiceInfo.setTaxRate("3");
            // 发票-支付-再生入库三表联查
            resultlist = invoiceInfoMapper.selectInvoicePaymentRefAndRenewableRef(invoiceInfo);

        }


        return resultlist;
    }


    @Override
    public List<InvoiceVo> queryInvoiceInfoList(InvoiceInfoDto invoiceInfo) {

        List<InvoiceVo> resultlist = new ArrayList<>(); // 发票关联支付
        if (StringUtils.isNotEmpty(invoiceInfo.getInNum()) || StringUtils.isNotEmpty(invoiceInfo.getOutNum())) {
            resultlist = invoiceInfoMapper.queryInvoiceInfoListByInNum(invoiceInfo);
            return resultlist;
        }
        if (StringUtils.isNotEmpty(invoiceInfo.getPaymentNum())) {
            resultlist = invoiceInfoMapper.queryInvoiceInfoListByPaymentNum(invoiceInfo);

            return resultlist;
        }

        resultlist = invoiceInfoMapper.queryInvoiceInfoList(invoiceInfo);


        return resultlist;


    }

    /**
     * 查询发票信息详情
     *
     * @param invoiceInfo
     * @return
     */
    @Override
    public List<PaymentInfoVo> details(InvoiceInfoDto invoiceInfo) {
        // 1. 返回关联支付单信息
        //根据完税id 找到 支付单
        List<PaymentInfoVo> paymentInfoVos = paymentInfoMapper.queryGetPaymentListByInvoiceId(invoiceInfo.getId());
        return paymentInfoVos;
    }


    @Override
    public List<PaymentInfoVo> queryInvoicePaymentInfoRefList(String invoiceId) {

        //        更新最新的剩余汇总金额
//        paymentInfoMapper.updateInvoiceInfoPaymentInfoRefTotalUseAmount();

        List<PaymentInfoVo> paymentInfoVos = invoiceInfoMapper.queryInvoicePaymentInfoRefList(invoiceId);
        if (paymentInfoVos != null && !paymentInfoVos.isEmpty()) {
            paymentInfoVos.forEach(paymentInfoVo -> paymentInfoVo.setPayTime(paymentInfoVo.getPayTime().substring(0, 10)));

        }
        return paymentInfoVos;
    }


    @Override
    public int deleteInvoicePaymentUseAmountList(String invoiceId, String paymentId) {
        return invoiceInfoMapper.deleteInvoicePaymentUseAmountList(invoiceId, paymentId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchSaveWarehouse(List<InvoiceWarehouseRef> dtoList) {
        int saveBatch = 0;
        List<InvoiceWarehouseRef> newList = new ArrayList<>();
        if (!dtoList.isEmpty()) {
            for (InvoiceWarehouseRef po : dtoList) {


                if (StringUtils.isNotEmpty(po.getInvoiceNum()) && StringUtils.isNotEmpty(po.getWarehouseNum())) {
                    po.setId(MD5Utils.md5(po.getInvoiceNum() + po.getWarehouseNum() + po.getSellerName() + po.getBuyerName() + po.getPlateNo()));
                    po.setCreateDate(DateUtils.getCurrentTime());
                    newList.add(po);
                } else if ("41110101".equalsIgnoreCase(po.getOrgCode())) {
                    po.setId(po.getUid());
                    po.setWarehouseNum(po.getUid() );
                    po.setCreateDate(DateUtils.getCurrentTime());
                    newList.add(po);
                }


            }

            String[] invoiceNumArr = newList.stream()
                    .map(InvoiceWarehouseRef::getInvoiceNum) // 提取出 invoiceNum
                    .distinct()                        // 去重
                    .toArray(String[]::new);

            String[] warehouseNumArr = newList.stream()
                    .map(InvoiceWarehouseRef::getWarehouseNum) // 提取出 invoiceNum
                    .distinct()                        // 去重
                    .toArray(String[]::new);
            if (warehouseNumArr != null && warehouseNumArr.length > 0) {
                //             导入之前 先删除
                invoiceInfoMapper.batchDeleteWarehouse(invoiceNumArr, warehouseNumArr);
            }
            if (newList != null && newList.size() > 0) {

                saveBatch = invoiceInfoMapper.bachSaveInWarehouse(newList);
            }

        }

        return saveBatch;
    }

    @Override
    public int batchSavePaymentRef(List<InvoiceInfoPaymentRef> dtoList) {
        int saveBatch = 0;
        List<InvoiceInfoPaymentRef> newList = new ArrayList<>();
        if (!dtoList.isEmpty()) {
            for (InvoiceInfoPaymentRef po : dtoList) {
                if (po.getPaymentNum() == null || po.getPaymentNum().isEmpty() || po.getInvoiceNum() == null) {
                    continue; // 如果 paymentNum 为空，则跳过当前循环
                }
                po.setId(MD5Utils.md5(po.getInvoiceNum() + po.getPaymentNum()));
                po.setInvoiceId(MD5Utils.md5(po.getInvoiceNum()));
                po.setPaymentId(MD5Utils.md5(po.getPaymentNum()));
                po.setCreateDate(DateUtils.getCurrentTime());
                newList.add(po);
            }


            String[] arr = newList.stream()
                    .map(InvoiceInfoPaymentRef::getInvoiceNum) // 提取出 invoiceNum
                    .distinct()                        // 去重
                    .toArray(String[]::new);

//             导入之前 先删除
            invoiceInfoMapper.batchDelete(arr);

            saveBatch = invoiceInfoMapper.bachSavePaymentRef(newList);
        }

        return saveBatch;
    }


    @Override
    public List<HashMap<String, Object>> querySettlementAmountByInvoiceNum(String invoiceNum) {
        return invoiceInfoMapper.querySettlementAmountByInvoiceNum(invoiceNum);
    }

    @Override
    public List<HashMap<String, Object>> queryPaymentAmountByInvoiceNum(String invoiceNum) {
        return invoiceInfoMapper.queryPaymentAmountByInvoiceNum(invoiceNum);
    }

    @Override
    public List<HashMap<String, Object>> queryContractInfoByInvoiceNum(String invoiceNum) {
        return invoiceInfoMapper.queryContractInfoByInvoiceNum(invoiceNum);
    }

    @Override
    public int bachSaveDetails(List<InvoiceDetails> dtoList) {
        int saveBatch = 0;
        if (!dtoList.isEmpty()) {
            for (InvoiceDetails po : dtoList) {
                // 如果 po.getDigitalInvoiceNum() 非空，则设置为 InvoiceNum
                if (StringUtils.isNotEmpty(po.getDigitalInvoiceNum())) {
                    po.setInvoiceNum(po.getDigitalInvoiceNum());
                }
                po.setId(MD5Utils.md5(po.getInvoiceNum() + po.getGoodsName() + po.getSpecification() + po.getGoodsUnit() + po.getGoodsQuantity() + po.getAmount() + po.getTotalAmount() + po.getSno()));

                po.setCreateDate(DateUtils.getCurrentTime());
            }
            String[] invoiceNums = dtoList.stream()
                    .map(InvoiceDetails::getInvoiceNum) // 提取出 invoiceNum
                    .distinct()                        // 去重
                    .toArray(String[]::new);

            invoiceInfoMapper.batchDeleteDetails(invoiceNums);

            saveBatch = invoiceInfoMapper.bachSaveDetails(dtoList);
        }
        return saveBatch;
    }

    @Override
    public List<InvoiceDetails> importInvoiceDetails(MultipartFile file, String sheetName, int rowNum) throws Exception {
        byte[] fileBytes = file.getBytes();
        List<InvoiceDetails> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, InvoiceDetails.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }

    @Override
    public int bachSave(List<InvoiceInfo> dtoList) {
        int saveBatch = 0;
        if (!dtoList.isEmpty()) {
            for (InvoiceInfo po : dtoList) {
                try {
                    // 如果 po.getDigitalInvoiceNum() 非空，则设置为 InvoiceNum
                    if (StringUtils.isNotEmpty(po.getDigitalInvoiceNum())) {
                        po.setInvoiceNum(po.getDigitalInvoiceNum());
                    }

                    // 设置 id，如果这里抛出异常，则会跳转到 catch 块
                    po.setId(MD5Utils.md5(po.getInvoiceNum()));

                    // 设置创建用户和创建时间
                    po.setCreateUser(SecurityUtils.getUsername());
                    po.setCreateDate(DateUtils.getCurrentTime());
                    po.setInvoiceTitle(po.getBuyerName());
                } catch (Exception e) {
                    // 捕获异常后继续下一个循环
                    System.err.println("这一条数据导入失败" + po.getInvoiceNum() + ", skipping this entry.");
                    continue; // 跳过当前循环，进入下一次循环
                }
            }
            saveBatch = invoiceInfoMapper.batchSave(dtoList);
        }
        invoiceInfoMapper.flushInvoiceImg();
//         批量刷图片
        return saveBatch;
    }

    @Override
    public List<InvoiceInfo> importInfo(MultipartFile file, String sheetName, int rowNum) throws Exception {
        // 获取文件的Base64编码
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<InvoiceInfo> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, InvoiceInfo.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }

    @Override
    public List<InvoiceWarehouseRef> importInfoWarehouse(MultipartFile file, String sheetName, int rowNum) throws Exception {
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<InvoiceWarehouseRef> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, InvoiceWarehouseRef.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }


    @Override
    public List<InvoiceContractRef> importInfoContractRef(MultipartFile file, String sheetName, int rowNum) throws Exception {
        byte[] fileBytes = file.getBytes();
        List<InvoiceContractRef> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, InvoiceContractRef.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }

    @Override
    public int bachSaveContractRef(List<InvoiceContractRef> dtoList) {
        int saveBatch = 0;
        if (!dtoList.isEmpty()) {
            for (InvoiceContractRef po : dtoList) {
                if (StringUtils.isEmpty(po.getInvoiceNum()) || StringUtils.isEmpty(po.getContractNum())) {
                    continue;
                }
                po.setId(MD5Utils.md5(po.getInvoiceNum() + po.getContractNum()));
                po.setContractId(MD5Utils.md5(po.getContractNum()));
                po.setInvoiceId(MD5Utils.md5(po.getInvoiceNum()));
                po.setCreateDate(DateUtils.getCurrentTime());
            }
            saveBatch = invoiceInfoMapper.bachSaveContractRef(dtoList);
        }
        return saveBatch;
    }

    @Override
    public int updateLogisticsStatusByInvoiceNum(InvoiceInfo invoiceInfo) {
        return invoiceInfoMapper.updateLogisticsStatusByInvoiceNum(invoiceInfo.getLogisticsStatus(), invoiceInfo.getInvoiceNum());
    }

    @Override
    public DashboardVo queryInvoiceInfoAgg(String category, String warehouseNum, String settlementAmount, String buyerName, String sellerName) {
        DashboardVo dashboardVo = invoiceInfoMapper.queryInvoiceInfoAgg(category, warehouseNum, settlementAmount, buyerName, sellerName);
        return dashboardVo;
    }

    @Override
    public List<InvoiceInfoPaymentRef> importInfoPurchasePayment(MultipartFile file, String sheetName, int rowNum) throws Exception {
        // 获取文件的Base64编码
        byte[] fileBytes = file.getBytes();
        // 解析excel文件获取数据集合
        List<InvoiceInfoPaymentRef> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, InvoiceInfoPaymentRef.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }


    /**
     * 新增发票信息
     *
     * @param invoiceInfo 发票信息
     * @return 结果
     */
    @Override
    public int insertInvoiceInfo(InvoiceInfo invoiceInfo) {

        // 设置录入人
        invoiceInfo.setCreateUser(SecurityUtils.getUsername());
        // 设置创建日期
        invoiceInfo.setCreateDate(DateUtils.getCurrentTime());
        // 设置开票时间
        return invoiceInfoMapper.insertInvoiceInfo(invoiceInfo);
    }


    /**
     * 修改发票信息
     *
     * @param invoiceInfo 发票信息
     * @return 结果
     */
    @Override
    public int updateInvoiceInfo(InvoiceInfo invoiceInfo) {
        if (StringUtils.isNotEmpty(invoiceInfo.getId())) {
            return invoiceInfoMapper.updateInvoiceInfo(invoiceInfo);
        }
        invoiceInfo.setId("FP" + MD5Utils.md5(invoiceInfo.getInvoiceNum()));
        int updateResult = invoiceInfoMapper.updateInvoiceInfo(invoiceInfo);
        if (0 == updateResult) {
            updateResult = insertInvoiceInfo(invoiceInfo);
        }

        return updateResult;


    }

    /**
     * 批量删除发票信息
     *
     * @param ids 需要删除的发票信息主键
     * @return 结果
     */
    @Override
    public int deleteInvoiceInfoByIds(String[] ids) {
/*        // 1. 删除该发票下关联的支付回单
        paymentInfoMapper.deletePaymentRefByInvoiceIds(ids);
        // 2. 删除该发票下关联的入库单（利废入库单、再生入库单）
        recyclingInInfoMapper.deleteRecyclingInRefById()
        renewableInInfoMapper.de*/

        return invoiceInfoMapper.deleteInvoiceInfoByIds(ids);
    }

    /**
     * 删除发票信息信息
     *
     * @param id 发票信息主键
     * @return 结果
     */
    @Override
    public int deleteInvoiceInfoById(String id) {
        return invoiceInfoMapper.deleteInvoiceInfoById(id);
    }


    public static void main(String[] args) throws ParseException {
//        String str = "2033-01-23";
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        Date date = sdf.parse(str);
//        System.out.println(date);

//            String input = "abc123def456";
//            Pattern pattern = Pattern.compile("\\d+");
//            Matcher matcher = pattern.matcher(input);
//
//            while (matcher.find()) {
//                System.out.println(matcher.group());
//            }

        String s = "24502000000008776005";
        String s1 = "24502000000026048596";
        System.out.println(s.length());
        System.out.println("2450200000000".length());
        System.out.println(s.substring(12, 20));
        System.out.println(s1.substring(12, 20));
    }
}
